package com.soap.desensitize.strategy.json;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.soap.desensitize.encry.IDesensitization;
import com.soap.desensitize.encry.json.AbstractJsonEncry;
import com.soap.desensitize.exception.strategy.DecodeException;
import com.soap.desensitize.exception.strategy.EncodeException;
import com.soap.desensitize.strategy.rreversible.symmetry.DesStrategy;
import com.soap.desensitize.util.JsonUtils;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.util.*;


public class JsonListStrategy extends AbstractJsonEncry<List> {

    public static Logger log = Logger.getLogger(JsonListStrategy.class);

    private JsonListStrategy() {
        super(DesStrategy.getInstance());
    }

    public JsonListStrategy(IDesensitization encry) {
        super(encry);
    }

    private static JsonListStrategy instance = null;

    /**
     * @return
     * @desc 获得实例
     */
    public static synchronized AbstractJsonEncry getInstance() {
        if (instance == null) {
            instance = new JsonListStrategy();
        }
        return instance;
    }

    /**
     * @param data
     * @param key
     * @return
     * @throws JsonProcessingException
     * @desc json转list
     */
    public List jsonToList(String data, String key) throws DecodeException {
        ObjectMapper objectMapper = new ObjectMapper();

        HashMap<String, Object> map = null;
        try {
            map = objectMapper.readValue(data, HashMap.class);
        } catch (JsonProcessingException e) {
            throw new DecodeException("解密错误，Json反序列化异常");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        List list = (List) map.values();
        return list;
    }


    /**
     * @desc 加密list
     * @param data
     * @return
     * @throws EncodeException
     */
    @Override
    public String encode(List data) throws EncodeException {

        try {
            List result = new ArrayList();
            for (int i = 0; i < data.size(); i++) {
                //判断类型
                result.add(JsonUtils.judgeAndEncode(data.get(i), this.getEncry()));
            }
            return new ObjectMapper().writeValueAsString(result);
        } catch (JsonProcessingException e) {
            throw new EncodeException("加密错误，Json加密异常");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @desc Json解密
     * @param data
     * @return
     * @throws DecodeException
     */
    @Override
    public List decode(String data) throws DecodeException {
        List list = null;
        List result = null;
        ObjectMapper mapper = new ObjectMapper();
        try {
            list = mapper.readValue(data, List.class);
            result = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                Object every = list.get(i);
                if (list.get(i).toString().contains("[") && list.get(i).toString().contains("]")) {
                    result.add(decode(every.toString()));
                }
                //map
                else if (list.get(i).toString().contains("{") && list.get(i).toString().contains("}")) {
                    result.add(JsonMapStrategy.getInstance(this.getEncry()).decode(every.toString()));
                } else {
                    result.add(JsonUtils.judgeAndDecode(every.toString(), this.getEncry()));
                }
            }
        } catch (JsonMappingException e) {
            throw new DecodeException("Json映射异常");
        } catch (JsonProcessingException e) {
            throw new DecodeException("Json处理异常");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    @Override
    public IDesensitization getEncry() {
        return super.getEncry();
    }

    @Override
    public void setEncry(IDesensitization encry) {
        super.setEncry(encry);
    }
}
